#include "videoplayer.h"
#include <QDebug>
#include <QImage>

VideoPlayer::VideoPlayer(QWidget *parent) : QWidget(parent)
{
    videoLabel = new QLabel(this);
    videoLabel->setAlignment(Qt::AlignCenter);
    videoLabel->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
    timer = new QTimer(this);
    connect(timer, &QTimer::timeout, this, &VideoPlayer::playNextFrame);
}

VideoPlayer::~VideoPlayer()
{
    // 释放资源
       if (swsCtx) sws_freeContext(swsCtx);
       if (rgbFrame) av_frame_free(&rgbFrame);
       if (frame) av_frame_free(&frame);
       if (codecCtx) avcodec_free_context(&codecCtx);
       if (formatCtx) avformat_close_input(&formatCtx);
}

bool VideoPlayer::openFile(const QString &filename)
{
    // 初始化 FFmpeg 上下文
    if (avformat_open_input(&formatCtx, filename.toUtf8().data(), nullptr, nullptr) != 0) {
        qDebug() << "Failed to open file";
        return false;
    }

    // 查找流信息
    if (avformat_find_stream_info(formatCtx, nullptr) < 0) {
        qDebug() << "Failed to find stream info";
        return false;
    }

    // 查找视频流
    for (int i = 0; i < formatCtx->nb_streams; i++) {
        if (formatCtx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
            videoStreamIndex = i;
            break;
        }
    }
    if (videoStreamIndex == -1) {
        qDebug() << "No video stream found";
        return false;
    }

    // 获取解码器
    AVCodecParameters *codecPar = formatCtx->streams[videoStreamIndex]->codecpar;
    const AVCodec *codec = avcodec_find_decoder(codecPar->codec_id);
    if (!codec) {
        qDebug() << "Unsupported codec";
        return false;
    }

    // 初始化解码器上下文
    codecCtx = avcodec_alloc_context3(codec);
    avcodec_parameters_to_context(codecCtx, codecPar);
    if (avcodec_open2(codecCtx, codec, nullptr) < 0) {
        qDebug() << "Failed to open codec";
        return false;
    }

    // 初始化帧和转换上下文
    frame = av_frame_alloc();
    rgbFrame = av_frame_alloc();
    int size = av_image_get_buffer_size(AV_PIX_FMT_RGB24, codecCtx->width, codecCtx->height, 1);
    uint8_t *buffer = (uint8_t *)av_malloc(size);
    av_image_fill_arrays(rgbFrame->data, rgbFrame->linesize, buffer, AV_PIX_FMT_RGB24,
                         codecCtx->width, codecCtx->height, 1);

    // 初始化 SWS 上下文（YUV -> RGB 转换）
    swsCtx = sws_getContext(codecCtx->width, codecCtx->height, codecCtx->pix_fmt,
                            codecCtx->width, codecCtx->height, AV_PIX_FMT_RGB24,
                            SWS_BILINEAR, nullptr, nullptr, nullptr);

    // 启动定时器（按帧率播放）
    double fps = av_q2d(formatCtx->streams[videoStreamIndex]->avg_frame_rate);
    timer->start(1000 / fps);
    return true;
}

void VideoPlayer::playNextFrame() {
    AVPacket packet;
    while (av_read_frame(formatCtx, &packet) >= 0) {
        if (packet.stream_index == videoStreamIndex) {
            // 发送数据包到解码器
            if (avcodec_send_packet(codecCtx, &packet) < 0) {
                qDebug() << "Error sending packet";
                break;
            }

            // 接收解码后的帧
            int ret = avcodec_receive_frame(codecCtx, frame);
            if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
                av_packet_unref(&packet);
                continue;
            } else if (ret < 0) {
                qDebug() << "Error receiving frame";
                break;
            }

            // 转换颜色空间到 RGB32
            sws_scale(swsCtx, frame->data, frame->linesize, 0, codecCtx->height,
                      rgbFrame->data, rgbFrame->linesize);

            // 创建 QImage 并显示
            QImage img(rgbFrame->data[0], codecCtx->width, codecCtx->height, QImage::Format_RGB888);
\
            // 等比例填充窗口
            QPixmap scaled = QPixmap::fromImage(img).scaled(size(),Qt::KeepAspectRatio,  Qt::SmoothTransformation);
            videoLabel->setPixmap(scaled);
            if(m_cacheSize != scaled.size())
            {
                m_cacheSize = scaled.size();
                videoLabel->resize(scaled.size());
            }

            break;
        }
        av_packet_unref(&packet);
    }
}
